
(function(window,document,Laya){
	var __un=Laya.un,__uns=Laya.uns,__static=Laya.static,__class=Laya.class,__getset=Laya.getset,__newvec=Laya.__newvec;

	var BaseMesh=laya.d3.resource.models.BaseMesh,BaseRender=laya.d3.core.render.BaseRender,BezierLerp=laya.ani.math.BezierLerp;
	var BlinnPhongMaterial=laya.d3.core.material.BlinnPhongMaterial,BoundBox=laya.d3.math.BoundBox,BoundFrustum=laya.d3.math.BoundFrustum;
	var BoundSphere=laya.d3.math.BoundSphere,BufferState=laya.d3.core.BufferState,Camera=laya.d3.core.Camera;
	var Color=laya.d3.math.Color,Event=laya.events.Event,GeometryElement=laya.d3.core.GeometryElement,Graphics=laya.display.Graphics;
	var HitResult=laya.d3.physics.HitResult,IndexBuffer3D=laya.d3.graphics.IndexBuffer3D,Keyboard=laya.events.Keyboard;
	var Laya3D=Laya.Laya3D,LayaGL=laya.layagl.LayaGL,Matrix4x4$1=laya.d3.math.Matrix4x4,MeshFilter=laya.d3.core.MeshFilter;
	var MeshSprite3D=laya.d3.core.MeshSprite3D,Plane=laya.d3.math.Plane,Ray=laya.d3.math.Ray,RenderContext3D=laya.d3.core.render.RenderContext3D;
	var RenderElement=laya.d3.core.render.RenderElement,RenderableSprite3D=laya.d3.core.RenderableSprite3D,Sprite3D=laya.d3.core.Sprite3D;
	var Stat=laya.utils.Stat,Transform3D=laya.d3.core.Transform3D,Vector2$1=laya.d3.math.Vector2,Vector3$1=laya.d3.math.Vector3;
	var Vector4$1=laya.d3.math.Vector4,VertexBuffer3D=laya.d3.graphics.VertexBuffer3D,VertexDeclaration=laya.d3.graphics.VertexDeclaration;
	var VertexElement=laya.d3.graphics.VertexElement,VertexElementFormat=laya.d3.graphics.VertexElementFormat;
	var VertexMesh=laya.d3.graphics.Vertex.VertexMesh,VertexPositionNormal=laya.d3.graphics.Vertex.VertexPositionNormal;
	var VertexPositionNormalColor=laya.d3.graphics.Vertex.VertexPositionNormalColor,WebGLContext=laya.webgl.WebGLContext;
/**
*TODO 范围选择实际要求并不精确，因此如果用到效率低的数学函数，可以考虑查表
*/
//class laya.d3Extend.worldMaker.Editor_3dController
var Editor_3dController=(function(){
	function Editor_3dController(camera){
		this.sel_obj=null;
		this.mat_World=null;
		// 选中对象之后，立即计算这个矩阵。
		this.camera=null;
		this.objs=[];
		/*
		private var pickEdgeObjID:int=-1;// 当前选中边的数据对象id
		private var pickEdgePtIdx:int=-1;// 当前选中边的起点的点id
		private var pickEdgeProjX:Number=0;// 当前选中边的投影点
		private var pickEdgeProjY:Number=0;
		private var pickEdgeDist2:Number=0;// 距离边的距离的平方
		*/
		this.editMode=true;
		this.ctrl=false;
		this.editor=null;
		this.point=new Vector2$1();
		this.mat_WVP=new Matrix4x4$1();
		this.camera=camera;
	}

	__class(Editor_3dController,'laya.d3Extend.worldMaker.Editor_3dController');
	var __proto=Editor_3dController.prototype;
	/**
	*把位置从本地空间转换到屏幕空间
	*@param position
	*@param out
	*/
	__proto.localToScreen=function(position,out){
		this.camera.viewport.project1(position,this.mat_WVP,out);
		var outE=out.elements;
		outE[0]=outE[0] / Laya.stage.clientScaleX;
		outE[1]=outE[1] / Laya.stage.clientScaleY;
	}

	//先
	__proto.selectObj=function(obj){
		if (this.sel_obj==obj)
			return;
		if (this.sel_obj){
			this.sel_obj.onUnselect();
		}
		this.sel_obj=obj;
		this.editor=obj.getEditor(this.camera);
		this.sel_obj.onSelect();
	}

	/**
	*摄像机改变了，需要重新计算控制点
	*/
	__proto.onCameraChange=function(){
		if (!this.editor)
			return;
		this.editor.onCameraChange();
	}

	/**
	*把一个世界空间的Ray转换成本地空间
	*@param ray
	*@param matrix
	*@param rayLocal
	*/
	__proto.RayToLocal=function(ray,matrix,rayLocal){
		var o=ray.origin.elements;
		var d=ray.direction.elements;
		var m=matrix.elements;
		var dx=o[0]-m[12];
		var dy=o[1]-m[13];
		var dz=o[2]-m[14];
		var oo=rayLocal.origin.elements;
		oo[0]=dx *m[0]+dy *m[1]+dz *m[2];
		oo[1]=dx *m[4]+dy *m[5]+dz *m[6];
		oo[2]=dx *m[8]+dy *m[9]+dz *m[10];
		var od=rayLocal.direction.elements;
		od[0]=d[0] *m[0]+d[1] *m[1]+d[2] *m[2];
		od[1]=d[0] *m[4]+d[1] *m[5]+d[2] *m[6];
		od[2]=d[0] *m[8]+d[1] *m[9]+d[2] *m[10];
	}

	/**
	*这个平面的法线是不是基本上对着屏幕，这样就可以基于2d来编辑。否则不要编辑
	*给的参数是本地坐标的
	*@param normX
	*@param normY
	*@param normZ
	*@return 0法线垂直，平面平行，无法编辑 1 最好
	*/
	__proto.fitForScrDrag=function(normX,normY,normZ){
		var ce=this.camera.viewMatrix.elements;
		var d=Math.abs(ce[8] *normX+ce[9] *normY+ce[10] *normZ);
		return d;
	}

	__proto.renderVisualData=function(g){
		if (!this.editor)
			return;
		g.clear();
		this.editor.renderVisualData(g);
	}

	__proto.onMouseMov=function(e){
		if (!this.editor)
			return;
		this.editor.onMouseMov(e);
	}

	__proto.onMouseDown=function(e){
		if (!this.editor)
			return;
		this.editor.onMouseDown(e);
	}

	__proto.onMouseUp=function(e){
		if (!this.editor)
			return;
		this.editor.onMouseUp(e);
	}

	__proto.onDbClick=function(e){
		if (!this.editor)
			return;
		this.editor.onDbClick(e);
	}

	__proto.onKeyDown=function(e){
		this.editor && this.editor.onKeyDown(e);
		if (e._stoped)
			return;
		switch(e.keyCode){
			case 27:
				break ;
			case 9:
				this.editMode=!this.editMode;
				break ;
			case 48:
				this.selectObj(this.objs[0]);
				break ;
			case 49:
				this.selectObj(this.objs[1]);
				break ;
			case 50:
			case 51:
			case 52:
			case 53:
			case 54:
			case 55:
			case 56:
			case 57:
				break ;
			case 96:
				break ;
			case 103:
				break ;
			case 99:
				break ;
			case 17:
				this.ctrl=true;
				break ;
			case 83:
				break ;
			}
	}

	__proto.onKeyUp=function(e){
		this.editor && this.editor.onKeyUp(e);
		switch (e.keyCode){
			case 17:
				this.ctrl=false;
				break ;
			}
	}

	return Editor_3dController;
})()


//class laya.d3Extend.worldMaker.HandlePoint
var HandlePoint=(function(){
	function HandlePoint(_x,_y,_ctrlx,_ctrly){
		this.x=NaN;
		this.y=NaN;
		this.ctrlx=NaN;
		// 控制点
		this.ctrly=NaN;
		this.x=_x;this.y=_y;this.ctrlx=_ctrlx;this.ctrly=_ctrly;
	}

	__class(HandlePoint,'laya.d3Extend.worldMaker.HandlePoint');
	return HandlePoint;
})()


//class laya.d3Extend.worldMaker.IRenderableMesh
var IRenderableMesh=(function(){
	function IRenderableMesh(){
		this.pos=null;
		this.normal=null;
		this.uv=null;
		this.color=null;
		this.roughness=null;
		this.metaless=null;
		this.index=null;
	}

	__class(IRenderableMesh,'laya.d3Extend.worldMaker.IRenderableMesh');
	return IRenderableMesh;
})()


//class laya.d3Extend.worldMaker.LE_Mesh
var LE_Mesh=(function(){
	var LEM_RenderableMesh,LEM_Material,LEM_Face,LEM_Edge,LEM_Vert;
	function LE_Mesh(){
		this.faceList=[];
		this.vertexList=[];
		this.edgeList=[];
		this.mtlList=[new LEM_Material(1,1,1,1,0,1)];
		this.bbx=[0,0,0,1,1,1];
		//包围盒
		this.leftIsInner=false;
		this.changedVertex=[];
	}

	__class(LE_Mesh,'laya.d3Extend.worldMaker.LE_Mesh');
	var __proto=LE_Mesh.prototype;
	__proto.getVec3=function(){
		if(LE_Mesh.vec3pool.length){
			var ret=LE_Mesh.vec3pool.pop();
			ret[0]=ret[1]=ret[2]=0;
			return ret;
		}
		return new Float32Array(3);
	}

	__proto.releaseVec3=function(v){
		if(v){
			LE_Mesh.vec3pool.push(v);
			return;
		}
	}

	__proto.Vec3Cross=function(out,a,b){
		var ax=a[0],ay=a[1],az=a[2];
		var bx=b[0],by=b[1],bz=b[2];
		out[0]=ay *bz-az *by;
		out[1]=az *bx-ax *bz;
		out[2]=ax *by-ay *bx;
		return out;
	}

	__proto.Vec3Normalize=function(out,a){
		var x=a[0];
		var y=a[1];
		var z=a[2];
		var len=x*x+y*y+z*z;
		if (len > 0){
			len=1 / Math.sqrt(len);
			out[0]=a[0] *len;
			out[1]=a[1] *len;
			out[2]=a[2] *len;
		}
		return out;
	}

	/**
	*添加一个新的顶点属性，返回槽id。pos,normal,uv都不算。
	*@param name
	*@param type
	*/
	__proto.addStaticElement=function(name,type){
		return 0;
	}

	/**
	*根据横截面和缩放边线建立mesh
	*@param cross_section 二维横截面，注意只有x，y
	*@param tapePath 缩放和移动，x是缩放，y是高度，x可以为负
	*
	*根据侧面的第一个点和最后一个点的相对位置来确定内外
	*最后 一个点高于第一个点就是线的左面为内，否则就是右面为内
	*横截面的方向不影响法线。
	*
	*注意：
	*现在法线计算不太对，因此为了效果正确，要求 cross_section 必须是顺时针。taperPath必须从下往上。
	*/
	__proto.createFromCrossSection_taperPath=function(cross_section,close,taperPath,posModifier){
		var _$this=this;
		if (cross_section.length < 4)
			return;
		if (taperPath.length < 4)
			return;
		var myverts=this.vertexList;
		var myedges=this.edgeList;
		var myfaces=this.faceList;
		myverts.length=0;
		myedges.length=0;
		myfaces.length=0;
		var ptnum=cross_section.length/2;
		var tapePtNum=taperPath.length/2;
		this.leftIsInner=taperPath[1] < taperPath[taperPath.length-1];
		var ti=0;
		var facePitch=close?ptnum:ptnum-1;
		var hEdgePitch=facePitch;
		var vEdgePitch=ptnum;
		var hvEdgePitch=hEdgePitch+vEdgePitch;
		var dx=0;
		var dy=0;
		var dz=0;
		for(var yi=0;yi<tapePtNum;yi++){
			var curs=taperPath[ti++];
			var cury=taperPath[ti++];
			for(var ci=0;ci<cross_section.length;){
				var curx=cross_section[ci++]*curs;
				var curz=cross_section[ci++]*curs;
				var curV=new LEM_Vert();
				myverts.push(curV);
				curV.x=curx;curV.y=cury;curV.z=curz;
				posModifier && posModifier(curV,ci,yi);
			}
		};
		var vi=0;
		for(yi=0;yi<tapePtNum-1;yi++){
			for (ci=0;ci < ptnum;ci++){
				var cv=myverts[vi];
				var nv=myverts[vi+ptnum];
				vi++;
				dx=nv.x-cv.x;dy=nv.y-cv.y;dz=nv.z-cv.z;
				cv.binnor.elements[0]=dx;
				cv.binnor.elements[1]=dy;
				cv.binnor.elements[2]=dz;
			}
		}
		vi=yi *ptnum;
		for (ci=0;ci < ptnum;ci++){
			var cv=myverts[vi];
			var lv=myverts[vi-ptnum];
			vi++;
			lv.binnor.cloneTo(cv.binnor);
		}
		for(yi=0;yi<tapePtNum;yi++){
			var bottomy=yi===tapePtNum-1;
			for(var xi=0;xi<ptnum;xi++){
				var xend=xi===ptnum-1;
				if(close || !xend){
					var e0=new LEM_Edge();
					myedges.push(e0);
					e0.v1=ptnum*yi+xi;myverts[e0.v1].addEdge(myedges.length-1);
					e0.v2=ptnum*yi+(xi+1)%ptnum;myverts[e0.v2].addEdge(myedges.length-1);
					if(!bottomy)e0.addFace(facePitch*yi+xi);
					if(yi!=0)e0.addFace(facePitch*yi+xi-facePitch);
					this.calcEdgeInfo(e0);
				}
				if(!bottomy){
					var e1=new LEM_Edge();
					myedges.push(e1);
					e1.v1=ptnum*yi+xi;myverts[e1.v1].addEdge(myedges.length-1);
					e1.v2=ptnum*(yi+1)+xi;myverts[e1.v2].addEdge(myedges.length-1);
					e1.f=[facePitch*yi+xi];
					if(xi===0){
						if(close)e1.addFace(facePitch*yi+facePitch-1)
							}else{
						e1.addFace(e1.f[0]-1);
					}
					this.calcEdgeInfo(e1);
				}
				if(!bottomy){
					if(close || !xend){
						var cf=new LEM_Face();
						var fid=myfaces.length;
						myfaces.push(cf);
						var cxi=yi*ptnum+xi;
						var cei=hvEdgePitch*yi+xi*(bottomy?1:2);
						cf.e=[cei,cei+1,cei+3,cei+hvEdgePitch];
						if(xend)cf.e[2]=hvEdgePitch*yi+1;
						if(yi===tapePtNum-2){
							cf.e[3]-=xi;
						}
						cf.v=[cxi,yi*ptnum+(xi+1)%ptnum,(yi*ptnum+(xi+1)%ptnum+ptnum),cxi+ptnum];
						myverts[cf.v[0]].addFace(fid);
						myverts[cf.v[1]].addFace(fid);
						myverts[cf.v[2]].addFace(fid);
						myverts[cf.v[3]].addFace(fid);
						this.calcFaceNormal(cf);
					}
				}
			}
		};
		var fn0=this.getVec3();
		myverts.forEach(function(v){
			fn0[0]=fn0[1]=fn0[2]=+0;
			v.faces.forEach(function(fv){
				var cf=myfaces[fv];
				fn0[0]+=cf.nx;fn0[1]+=cf.ny;fn0[2]+=cf.nz;
			});
			_$this.Vec3Normalize(fn0,fn0);
			v.nx=fn0[0],v.ny=fn0[1],v.nz=fn0[2];
		});
		this.releaseVec3(fn0);
	}

	__proto.calcEdgeInfo=function(e){
		if(e.flags&(1<<LEM_Edge.FLAG_LENGTH))
			return;
		var v1=this.vertexList[e.v1];
		var v2=this.vertexList[e.v2];
		e.dx=v2.x-v1.x;
		e.dy=v2.y-v1.y;
		e.dz=v2.z-v1.z;
		e.len=Math.sqrt(e.dx*e.dx+e.dy*e.dy+e.dz*e.dz);
		e.flags|=(1<<LEM_Edge.FLAG_LENGTH);
	}

	__proto.calcFaceNormal=function(f){
		var tmpArr=[];
		for(var ei=0;ei<f.e.length;ei++){
			var e1=this.edgeList[f.e[ei]];
			if(e1.len<=0)continue ;
			tmpArr.push(e1);
			if(tmpArr.length==2)break ;
		};
		var fn=this.getVec3();
		var v1=this.getVec3();
		var v2=this.getVec3();
		v1[0]=tmpArr[0].dx;v1[1]=tmpArr[0].dy;v1[2]=tmpArr[0].dz;
		v2[0]=tmpArr[1].dx;v2[1]=tmpArr[1].dy;v2[2]=tmpArr[1].dz;
		this.Vec3Cross(fn,v1,v2);
		this.Vec3Normalize(fn,fn);
		f.nx=fn[0];
		f.ny=fn[1];
		f.nz=fn[2];
		this.releaseVec3(v1);this.releaseVec3(v2);this.releaseVec3(fn);
	}

	/**
	*计算指定顶点的法线
	*@param vetexid
	*/
	__proto.updateVertNormal=function(vetexid){
		var _$this=this;
		vetexid.forEach(function(v){
			_$this.calcVertNormal(_$this.vertexList[v]);
		});
	}

	__proto.calcVertNormal=function(v){
		var fn=v.faces.length;
		var sum=this.getVec3();
		sum[0]=0,sum[1]=0,sum[2]=0;
		for(var i=0;i<fn;i++){
			var cf=this.faceList[v.faces[i]];
			sum[0]+=cf.nx;
			sum[1]+=cf.ny;
			sum[2]+=cf.nz;
		};
		var nn=this.getVec3();
		this.Vec3Normalize(nn,sum);
		v.nx=nn[0],v.ny=nn[1],v.nz=nn[2];
		this.releaseVec3(sum);
		this.releaseVec3(nn);
	}

	/**
	*更新某个范围内的顶点的法线
	*@param start
	*@param end 结束位置，不含。
	*/
	__proto.clacVerteNormalFromTo=function(start,end){
		for(var i=start;i<end;i++){
			var cv=this.vertexList[i];
			this.calcVertNormal(cv);
		}
	}

	/**
	*某个顶点被修改了。
	*@param vid
	*/
	__proto.onVertexChanged=function(vid){
		this.changedVertex.push(vid);
	}

	/**
	*只是顶点的位置改变了。拓扑信息不变。需要重新计算相关部分的法线
	*/
	__proto.onChangeEnd=function(){
		var _$this=this;
		var changedfaces=[];
		var myverts=this.vertexList;
		this.changedVertex.forEach(function(vid){
			var faces=myverts[vid].faces;
			faces.forEach(function(fid){
				var cface=_$this.faceList[fid];
				if(cface.udata===0){
					_$this.calcFaceNormal(cface);
					cface.udata=1;
					changedfaces.push(cface);
				}
			})
		});
		this.changedVertex.forEach(function(vid){
			var cv=myverts[vid];
			_$this.calcVertNormal(cv);
		});
		changedfaces.forEach(function(f){f.udata=0;});
	}

	/**
	*
	*@param off vec3
	*/
	__proto.translateVertex=function(off){
		var _$this=this;
		var vts=this.vertexList;
		function rnd (){
			return (Math.random()-0.5)/20;
		}
		vts.forEach(function(vert,i){
			vert.x+=rnd();
			vert.y+=rnd();
			vert.z+=rnd();
			_$this.onVertexChanged(i);
		});
		this.onChangeEnd();
	}

	/**
	*导出内部的mesh数据为三角形数据
	*只导出face，单独的点，线都不导出
	*这里只考虑快速导出，不考虑优化
	*统一按照逆时针导出三角形
	*@param polygonType 多边形风格， 0 是原始数据 1 是完全打散成三角形，2 是原始face 3 是根据接缝分平滑组
	*/
	__proto.fastExportRenderableMesh=function(polygonType){
		if(polygonType===1){
			return this.fastExportRenderableMesh_tri();
		};
		var ret=new LEM_RenderableMesh();
		this.vertexList.forEach(function(v){
			v.expid=-1;
		});
		var pos=[];
		var idx=[];
		var norm=[];
		var color=[];
		for(var fi=0;fi<this.faceList.length;fi++){
			var cf=this.faceList[fi];
			var cmtl=this.mtlList[cf.mtl];
			var vn=cf.v.length;
			var fn=vn-2;
			for(var vi=0;vi<vn;vi++){
				var cv=this.vertexList[cf.v[vi]];
				if(cv.expid<0){
					pos.push(cv.x,cv.y,cv.z);
					norm.push(cv.nx,cv.ny,cv.nz);
					cv.expid=(pos.length-3)/3;
					color.push(cmtl.r,cmtl.g,cmtl.b,cmtl.a);
				}
			}
			for(var trii=0;trii<fn;trii++){
				var v0=this.vertexList[cf.v[0]].expid;
				var v1=this.vertexList[cf.v[trii+1]].expid;
				var v2=this.vertexList[cf.v[trii+2]].expid;
				idx.push(v0,v2,v1);
			}
		}
		this.vertexList.forEach(function(v){
			if(v.expid>=0){}
				});
		ret.index=new Uint16Array(idx);
		ret.pos=new Float32Array(pos);
		ret.normal=new Float32Array(norm);
		ret.uv=new Float32Array(pos.length*2/3);
		ret.color=new Float32Array(color);
		return ret;
	}

	/**
	*导出多边形风格。每个面使用统一的法线
	*@param tri 使用纯三角形。如果是false则表示整个面共享法线
	*/
	__proto.fastExportRenderableMesh_tri=function(tri){
		(tri===void 0)&& (tri=false);
		var ret=new LEM_RenderableMesh();
		var pos=[];
		var idx=[];
		var norm=[];
		var color=[];
		var cidx=0;
		var fNormal=this.getVec3();
		for(var fi=0;fi<this.faceList.length;fi++){
			var cf=this.faceList[fi];
			var cmtl=this.mtlList[cf.mtl];
			fNormal[0]=cf.nx;fNormal[1]=cf.ny;fNormal[2]=cf.nz;
			var vn=cf.v.length;
			if(!tri){
				var stVert=pos.length/3;
				for(var vi=0;vi<vn;vi++){
					var v=this.vertexList[cf.v[vi]];
					pos.push(v.x,v.y,v.z);
					color.push(cmtl.r,cmtl.g,cmtl.b,cmtl.a);
					norm.push(fNormal[0],fNormal[1],fNormal[2]);
				}
				for(vi=0;vi<vn-2;vi++){
					idx.push(stVert,stVert+vi+2,stVert+vi+1);
				}
				}else{
				var v0=this.vertexList[cf.v[0]];
				for(vi=0;vi<vn-2;vi++){
					var v1=this.vertexList[cf.v[vi+1]];
					var v2=this.vertexList[cf.v[vi+2]];
					pos.push(v0.x,v0.y,v0.z,v1.x,v1.y,v1.z,v2.x,v2.y,v2.z);
					idx.push(cidx++,cidx++,cidx++);
					color.push(cmtl.r,cmtl.g,cmtl.b,cmtl.a);
					color.push(cmtl.r,cmtl.g,cmtl.b,cmtl.a);
					color.push(cmtl.r,cmtl.g,cmtl.b,cmtl.a);
					norm.push(fNormal[0],fNormal[1],fNormal[2],
					fNormal[0],fNormal[1],fNormal[2],
					fNormal[0],fNormal[1],fNormal[2]);
				}
			}
		}
		this.releaseVec3(fNormal);
		ret.index=new Uint16Array(idx);
		ret.pos=new Float32Array(pos);
		ret.normal=new Float32Array(norm);
		ret.uv=new Float32Array(pos.length*2/3);
		ret.color=new Float32Array(color);
		return ret;
	}

	LE_Mesh.vec3pool=[];
	LE_Mesh.__init$=function(){
		//class LEM_RenderableMesh
		LEM_RenderableMesh=(function(){
			function LEM_RenderableMesh(){
				this.pos=null;
				this.normal=null;
				this.uv=null;
				this.color=null;
				this.roughness=null;
				this.metaless=null;
				this.index=null;
			}
			__class(LEM_RenderableMesh,'');
			return LEM_RenderableMesh;
		})()
		//class LEM_Material
		LEM_Material=(function(){
			function LEM_Material(r,g,b,a,metaless,roughness){
				this.r=1;
				this.g=1;
				this.b=1;
				this.a=1;
				this.metaless=0;
				this.roughness=1;
				this.r=r,this.g=g,this.b=b,this.metaless=metaless,this.roughness=roughness;
			}
			__class(LEM_Material,'');
			return LEM_Material;
		})()
		//class LEM_Face
		LEM_Face=(function(){
			function LEM_Face(){
				//id=0 | 0;由于会删除，加上id会造成混乱
				this.v=null;
				// 顶点的索引。 必须是按照固定顺序。顺时针
				this.e=null;
				// 面的法线。面的法线用所有的三角面的加权平均值算
				this.nx=0.0;
				this.ny=0.0;
				this.nz=0.0;
				this.mtl=0;
				this.udata=0;
			}
			__class(LEM_Face,'');
			return LEM_Face;
		})()
		//临时用途。遍历使用。平时为0，不许持久使用，每个函数用完以后要归零
		//class LEM_Edge
		LEM_Edge=(function(){
			function LEM_Edge(){
				//id=0 | 0;
				this.flags=0|0;
				// 边的左右面的索引。现在先假设只能有两个面。 TODO 不对，三维中没有左右面的概念，除非指定什么是上
				this.f=null;
				// 边的两个点的索引
				this.v1=-1 | 0;
				this.v2=-1 | 0;
				this.len=+0.0;
				this.dx=+0.0;
				this.dy=+0.0;
				this.dz=+0.0;
			}
			__class(LEM_Edge,'');
			var __proto=LEM_Edge.prototype;
			__proto.addFace=function(fid){
				if(!this.f){
					this.f=[fid];
					return;
				}
				if(this.f.indexOf(fid)<0){
					this.f.push(fid);
				}
			}
			LEM_Edge.FLAG_LENGTH=0;
			return LEM_Edge;
		})()
		//class LEM_Vert
		LEM_Vert=(function(){
			function LEM_Vert(){
				//id=0 | 0;
				this.x=0;
				this.y=0;
				this.z=0;
				//法线
				this.nx=0;
				this.ny=0;
				this.nz=0;
				// 法线。 顶点的法线都是根据关联关系重新计算的，单个点没有法线，线的法线是根据线来算的
				this.u=0;
				this.v=0;
				// binormal ，v的变化方向。对于侧面线建立的模型，可以根据这个来确定用什么法线
				this.mtlid=-1;
				// 材质id
				this.otherStaticElement=null;
				// 其他静态属性，即mesh上所有点都相同的结构。可以任意添加
				this.edges=null;
				// 关联的边
				this.faces=null;
				//关联的面
				this.expid=-1;
				this.nor=new Vector3$1();
				this.binnor=new Vector3$1();
			}
			__class(LEM_Vert,'');
			var __proto=LEM_Vert.prototype;
			//导出的时候用，>=0表示当前点已经被导出到第expid位置了
			__proto.addEdge=function(id){
				if(!this.edges){
					this.edges=[id];
					return;
				}
				if(this.edges.indexOf(id)<0)
					this.edges.push(id);
			}
			__proto.addFace=function(id){
				if(!this.faces){
					this.faces=[id];
					return;
				}
				if(this.faces.indexOf(id)<0)
					this.faces.push(id);
			}
			return LEM_Vert;
		})()
	}

	return LE_Mesh;
})()


//class laya.d3Extend.worldMaker.Pick2DEdgeResult
var Pick2DEdgeResult=(function(){
	function Pick2DEdgeResult(){
		this.ObjID=-1;
		this.PtIdx=-1;
		// TODO 如果是图的话，用点来指示边是不对的
		this.projX=0;
		// 投影到线上点
		this.projY=0;
		this.dist2=0;
		// 投影点到自己的距离的平方
		this.offX=0;
		//距离实际点的距离
		this.offY=0;
	}

	__class(Pick2DEdgeResult,'laya.d3Extend.worldMaker.Pick2DEdgeResult');
	return Pick2DEdgeResult;
})()


//class laya.d3Extend.worldMaker.Pick2DResult
var Pick2DResult=(function(){
	function Pick2DResult(){
		this.miniObjID=-1;
		this.miniPointID=-1;
		this.miniDist=0;
		this.offX=0;
		//距离实际点的距离
		this.offY=0;
	}

	__class(Pick2DResult,'laya.d3Extend.worldMaker.Pick2DResult');
	return Pick2DResult;
})()


/**
*可以从通用sprite3d编辑器派生，额外提供simpleshapeFilter的编辑功能
*先直接假设编辑的就是mesh
*/
//class laya.d3Extend.worldMaker.SimpleShapeEditor
var SimpleShapeEditor=(function(){
	function SimpleShapeEditor(obj,cam){
		this.target=null;
		// 要编辑的对象
		this.editMode=true;
		// 编辑模式
		this.ctrl=false;
		this.worldEditor=null;
		// 提供一些通用方法。例如摄像机相关的 localToScreen
		this.mat_World=null;
		// 选中对象之后，立即计算这个矩阵。
		this.camera=null;
		//2d data
		this.crossDataOnScr=[];
		// 原始数据投影到屏幕上的位置。
		this.crossDataOnScrZ=[];
		// 每个点对应的z值。
		this.crossCtrlOnScr=[];
		this.crossCtrlOnScrZ=[];
		this.profileLineDataOnScr=[];
		//
		this.profileLineDataOnScrZ=[];
		this.profileCtrlOnScr=[];
		this.profileCtrlOnScrZ=[];
		this.interpNum=0;
		this.undoPos=0;
		// 当前undo可以开始的地方，通常是数组结尾，一旦undo了就离开了结尾，从 undoPos到结尾是可以redo的地方
		this.dataBeforeEdit={};
		// 整体undo用
		this.dataChanged=false;
		//编辑器是否对数据进行过修改。
		this.continueChangeSavedData=null;
		// 拖动前保存的cross或者profile数据
		this.dataChangedAfterStart=false;
		//按下鼠标后实际修改数据了
		this.curEditProp=null;
		this.ray=new Ray(new Vector3$1(0,0,0),new Vector3$1(0,0,0));
		this.mat_InvWorld=new Matrix4x4$1();
		this.mat_WVP=new Matrix4x4$1();
		this.point=new Vector2$1();
		this.pickResult=new Pick2DResult();
		this.pickEdgeResult=new Pick2DEdgeResult();
		this.undoStack=new Array(0);
		this.undoOp=new UndoOperation();
		this.target=obj;
		this.camera=cam;
		this.updateData();
	}

	__class(SimpleShapeEditor,'laya.d3Extend.worldMaker.SimpleShapeEditor');
	var __proto=SimpleShapeEditor.prototype;
	__proto.updateData=function(){
		var mesh=this.target._simpleShapeMesh;
		var wmat=this.mat_World=this.target._transform.worldMatrix;
		Matrix4x4$1.multiply(this.camera.viewMatrix,wmat,SimpleShapeEditor.tmpMat);
		Matrix4x4$1.multiply(this.camera.projectionMatrix,SimpleShapeEditor.tmpMat,this.mat_WVP);
		wmat.invert(this.mat_InvWorld);
		this.crossCtrlOnScr.length=this.crossDataOnScr.length=mesh.crossSectionData.length*2;
		this.crossCtrlOnScrZ.length=this.crossDataOnScrZ.length=this.crossDataOnScr.length;
		this.profileCtrlOnScr.length=this.profileLineDataOnScr.length=mesh.profileLineData.length*2;
		this.profileLineDataOnScrZ.length=this.profileLineDataOnScrZ.length=this.profileLineDataOnScr.length;
	}

	/**
	*进入编辑模式，开始编辑mesh
	*/
	__proto.enterEditMode=function(){}
	// 立即操作
	__proto.undo_op_changeInterp=function(bef,after){
		this.undo_pushUndoData({
			target:this.target._simpleShapeMesh,
			undo:function (){
				this.target.crossSectionInterpNum=bef;
				this.target.profileLineInterpNum=bef;
			},
			redo:function (){
				this.target.crossSectionInterpNum=after;
				this.target.profileLineInterpNum=after;
			}
		});
	}

	__proto.undo_op_changeStyle=function(bef,after){
		this.undo_pushUndoData({
			target:this.target._simpleShapeMesh,
			undo:function (){
				this.target.polygonStyle=bef;
			},
			redo:function (){
				this.target.polygonStyle=after;
			}
		});
	}

	__proto.copyHandlePointArray=function(dt){
		var ret=dt.concat();
		ret.forEach(function(v,i){
			ret[i]=new HandlePoint(v.x,v.y,v.ctrlx,v.ctrly);
		});
		return ret;
	}

	__proto.undo_startCrossData=function(){
		this.curEditProp="crossSectionData";
		this.dataChangedAfterStart=false;
		this.continueChangeSavedData=this.copyHandlePointArray(this.target._simpleShapeMesh.crossSectionData);
	}

	__proto.undo_startProfileData=function(){
		this.curEditProp="profileLineData";
		this.dataChangedAfterStart=false;
		this.continueChangeSavedData=this.copyHandlePointArray(this.target._simpleShapeMesh.profileLineData);
	}

	__proto.undo_drage_changeData=function(){
		this.dataChangedAfterStart=true;
	}

	__proto.undo_op_end=function(){
		if (this.dataChangedAfterStart){
			var newv=null;
			switch(this.curEditProp){
				case 'crossSectionData':
					newv=this.copyHandlePointArray(this.target._simpleShapeMesh.crossSectionData);
					break ;
				case 'profileLineData':
					newv=this.copyHandlePointArray(this.target._simpleShapeMesh.profileLineData);
					break ;
				default :
					throw "err158";
					break ;
				}
			this.undo_pushUndoData({
				target:this.target._simpleShapeMesh,
				oldv:this.continueChangeSavedData,
				newv:newv,
				prop:this.curEditProp,
				undo:function (){
					this.target[this.prop]=this.oldv;
				},
				redo:function (){
					this.target[this.prop]=this.newv;
				}
			});
		}
		this.curEditProp="";
		this.dataChangedAfterStart=false;
	}

	/**
	*当前位置就是数据的最终位置？
	*@param undoObj
	*/
	__proto.undo_pushUndoData=function(undoObj){
		if (this.undoPos < this.undoStack.length){
			this.undoStack[this.undoPos++]=undoObj;
			this.undoStack.length=this.undoPos;
		}
		else {
			this.undoStack.push(undoObj);
		}
		if (this.undoStack.length > SimpleShapeEditor.UndoStackLen){
			this.undoStack.shift();
		}
		this.undoPos=this.undoStack.length;
	}

	__proto.undo=function(){
		this.undoPos--;
		if (this.undoPos < 0){
			this.undoPos=0;
			return;
		};
		var ud=this.undoStack[this.undoPos];
		ud && ud.undo.call(ud);
		this.target._simpleShapeMesh.onDataChanged();
		this.updateData();
	}

	// 更新二维数据
	__proto.redo=function(){
		if (this.undoPos >=this.undoStack.length)
			return;
		var ud=this.undoStack[this.undoPos++];
		ud && ud.redo.call(ud);
		this.target._simpleShapeMesh.onDataChanged();
		this.updateData();
	}

	//更新二维数据
	__proto.onSelect=function(){
		var mesh=this.target._simpleShapeMesh;
		this.dataBeforeEdit.crossSectionData=this.copyHandlePointArray(mesh.crossSectionData);
		this.dataBeforeEdit.profileLineData=this.copyHandlePointArray(mesh.profileLineData);
	}

	__proto.onUnselect=function(){
		if (this.dataChanged){
			this.undoStack.length=0;
			this.dataChanged=false;
		}
	}

	/**
	*把位置从本地空间转换到屏幕空间
	*@param position
	*@param out
	*/
	__proto.localToScreen=function(position,out){
		this.camera.viewport.project1(position,this.mat_WVP,out);
		var outE=out.elements;
		outE[0]=outE[0] / Laya.stage.clientScaleX;
		outE[1]=outE[1] / Laya.stage.clientScaleY;
	}

	__proto.pick2DData=function(x,y,data,dist,result){
		var minid=-1;
		var miniDist=dist;
		var pickOffX=0;
		var pickOffY=0;
		var dtnum=data.length / 2;
		for (var i=0;i < dtnum;i++){
			var dx=data[i*2]-x;
			var dy=data[i*2+1]-y;
			var cdist=Math.sqrt(dx *dx+dy *dy);
			if (miniDist > cdist){
				miniDist=cdist;
				minid=i;
				pickOffX=dx;
				pickOffY=dy;
			}
		}
		if (minid >=0){
			result.miniPointID=minid;
			result.miniDist=miniDist;
			result.offX=pickOffX;
			result.offY=pickOffY;
			return result;
		}
		return null;
	}

	/**
	*点选算法。按照投影到屏幕上的二维点的距离来算，这样最自然。也方便以后转到gpu点选。
	*可能选中点，也可能选中边。如果都满足优先按照点来算
	*@param x
	*@param y
	*@param dist
	*@return
	*/
	__proto.pick=function(x,y,dist){
		(dist===void 0)&& (dist=70);
		this.pickResult.miniObjID=-1;
		if (this.pick2DData(x,y,this.crossDataOnScr,dist,this.pickResult)){
			this.pickResult.miniObjID=0;
			dist=this.pickResult.miniDist;
			this.undo_startCrossData();
			console.log('pick ',this.pickResult.miniPointID);
		}
		if (this.interpNum > 0){
			var resultcc=new Pick2DResult();
			if (this.pick2DData(x,y,this.crossCtrlOnScr,dist,resultcc)){
				this.pickResult=resultcc;
				this.pickResult.miniObjID=2;
				dist=this.pickResult.miniDist;
				this.undo_startCrossData();
			}
		};
		var result1=new Pick2DResult();
		if (this.pick2DData(x,y,this.profileLineDataOnScr,dist,result1)){
			this.pickResult=result1;
			this.pickResult.miniObjID=1;
			dist=result1.miniDist;
			this.undo_startProfileData();
		};
		var resultpc=new Pick2DResult();
		if (this.pick2DData(x,y,this.profileCtrlOnScr,dist,resultpc)){
			this.pickResult=resultpc;
			this.pickResult.miniObjID=3;
			this.undo_startProfileData();
		}
	}

	/**
	*返回是否靠近某条边，以及对应的最近的边上的点。
	*只有投影点落在两个点之间的才算，所以如果相邻边形成锐角，在尖角外面会有一个无效区域
	*@param x
	*@param y
	*/
	__proto.pickEdge=function(x,y,data,close,dist,result){
		result.PtIdx=-1;
		result.dist2=dist *dist;
		var dtnum=data.length / 2;
		var end=dtnum-1;
		if (close)end=dtnum;
		for (var i=0;i < end;i++){
			var st=i *2;
			var p0x=data[st];
			var p0y=data[st+1];
			var p1x=data[(st+2)%data.length];
			var p1y=data[(st+3)%data.length];
			var dx=p1x-p0x;
			var dy=p1y-p0y;
			var p0px=x-p0x;
			var p0py=y-p0y;
			var d2=dx *dx+dy *dy;
			if (d2 < 1e-6)
				continue ;
			var elen=Math.sqrt(d2);
			var ndx=dx / elen;
			var ndy=dy / elen;
			var dv=ndx *p0px+ndy *p0py;
			if (dv<0||dv>elen)
				continue ;
			var projx=p0x+ndx *dv;
			var projy=p0y+ndy *dv;
			var dx1=projx-x;
			var dy1=projy-y;
			d2=dx1 *dx1+dy1 *dy1;
			if (d2< result.dist2){
				result.dist2=d2;
				result.PtIdx=i;
				result.projX=projx;
				result.projY=projy;
			}
		}
		return result.PtIdx >=0?result:null;
	}

	/**
	*摄像机改变了，需要重新计算控制点
	*/
	__proto.onCameraChange=function(){
		if (!this.target)
			return;
		Matrix4x4$1.multiply(this.camera.viewMatrix,this.mat_World,SimpleShapeEditor.tmpMat);
		Matrix4x4$1.multiply(this.camera.projectionMatrix,SimpleShapeEditor.tmpMat,this.mat_WVP);
		var mesh=this.target._simpleShapeMesh;
		var scrPos=new Vector3$1();
		var hdata=mesh.crossSectionData;
		var hdatanum=hdata.length;
		for (var hi=0;hi < hdatanum;hi++){
			SimpleShapeEditor.tmpVec3.elements[0]=hdata[hi].x;
			SimpleShapeEditor.tmpVec3.elements[1]=0;
			SimpleShapeEditor.tmpVec3.elements[2]=hdata[hi].y;
			this.localToScreen(SimpleShapeEditor.tmpVec3,scrPos);
			this.crossDataOnScr[hi *2]=scrPos.x;
			this.crossDataOnScr[hi *2+1]=scrPos.y;
			this.crossDataOnScrZ[hi]=scrPos.z;
			SimpleShapeEditor.tmpVec3.elements[0]=hdata[hi].ctrlx;
			SimpleShapeEditor.tmpVec3.elements[1]=0;
			SimpleShapeEditor.tmpVec3.elements[2]=hdata[hi].ctrly;
			this.localToScreen(SimpleShapeEditor.tmpVec3,scrPos);
			this.crossCtrlOnScr[hi *2]=scrPos.x;
			this.crossCtrlOnScr[hi *2+1]=scrPos.y;
			this.crossCtrlOnScrZ[hi]=scrPos.z;
		};
		var cdata=mesh.profileLineData;
		var cdtNum=cdata.length;
		for (var ci=0;ci < cdtNum;ci++){
			SimpleShapeEditor.tmpVec3.elements[0]=cdata[ci].x;
			SimpleShapeEditor.tmpVec3.elements[1]=cdata[ci].y;
			SimpleShapeEditor.tmpVec3.elements[2]=0;
			this.localToScreen(SimpleShapeEditor.tmpVec3,scrPos);
			this.profileLineDataOnScr[ci *2]=scrPos.x;
			this.profileLineDataOnScr[ci *2+1]=scrPos.y;
			this.profileLineDataOnScrZ[ci]=scrPos.z;
			SimpleShapeEditor.tmpVec3.elements[0]=cdata[ci].ctrlx;
			SimpleShapeEditor.tmpVec3.elements[1]=cdata[ci].ctrly;
			SimpleShapeEditor.tmpVec3.elements[2]=0;
			this.localToScreen(SimpleShapeEditor.tmpVec3,scrPos);
			this.profileCtrlOnScr[ci *2]=scrPos.x;
			this.profileCtrlOnScr[ci *2+1]=scrPos.y;
			this.profileCtrlOnScrZ[ci]=scrPos.z;
		}
	}

	/**
	*平面用点法式，而不是现在的Plane类，因为需要一个点，且不想构造Plane
	*@param x
	*@param y
	*@param planePos
	*@param planeNormal
	*@param out
	*/
	__proto.scrToPlane=function(x,y,planePos,planeNormal,out){
		this.point.elements[0]=x;
		this.point.elements[1]=y;
		this.camera.viewportPointToRay(this.point,this.ray);
		var ro=this.ray.origin.elements;
		var rd=this.ray.direction.elements;
		var ppos=planePos.elements;
		var pnor=planeNormal.elements;
		var dx=ppos[0]-ro[0];
		var dy=ppos[1]-ro[1];
		var dz=ppos[2]-ro[2];
		var dist=dx *pnor[0]+dy *pnor[1]+dz *pnor[2];
		var v=rd[0] *pnor[0]+rd[1] *pnor[1]+rd[2] *pnor[2];
		var t=dist / v;
		out.elements[0]=ro[0]+rd[0] *t;
		out.elements[1]=ro[1]+rd[1] *t;
		out.elements[2]=ro[2]+rd[2] *t;
	}

	/**
	*把一个世界空间的坐标变成编辑对象本地空间的
	*@param wpos
	*@param lpos
	*/
	__proto.worldToLocal=function(wpos,lpos){
		Vector3$1.transformV3ToV3(wpos,this.mat_InvWorld,lpos);
	}

	__proto.deletePoint=function(objid,pointid){
		if (!this.target)
			return;
		var dt;
		if (objid==0){
			this.undo_startCrossData();
			this.undo_drage_changeData();
			dt=this.target._simpleShapeMesh.crossSectionData;
			dt.splice(pointid,1);
			this.target._simpleShapeMesh.setCrossSection(dt);
			this.undo_op_end();
			}else if(objid==1){
			this.undo_startProfileData();
			this.undo_drage_changeData();
			dt=this.target._simpleShapeMesh.profileLineData;
			dt.splice(pointid,1);
			this.target._simpleShapeMesh.setProfileLine(dt);
			this.undo_op_end();
			}else {
			console.log("不能删除这个点");
		}
		this.updateData();
		this.pickResult.miniObjID=-1;
	}

	// 撤销当前选择
	__proto.addPoint=function(x,y){
		var dist=70;
		this.pickEdgeResult.ObjID=-1;
		if (this.pickEdge(x,y,this.crossDataOnScr,true,dist,this.pickEdgeResult)){
			this.pickEdgeResult.ObjID=0;
			dist=Math.sqrt(this.pickEdgeResult.dist2);
		};
		var result1=new Pick2DEdgeResult();
		if (this.pickEdge(x,y,this.profileLineDataOnScr,false,dist,result1)){
			this.pickEdgeResult=result1;
			this.pickEdgeResult.ObjID=1;
		};
		var dt;
		var stid=0;
		if (this.pickEdgeResult.ObjID==0){
			this.undo_startCrossData();
			this.undo_drage_changeData();
			dt=this.target._simpleShapeMesh.crossSectionData;
			stid=this.pickEdgeResult.PtIdx+1;
			this.scrToLocalPlane(this.pickEdgeResult.projX,this.pickEdgeResult.projY,SimpleShapeEditor.LOCAL_XZ,SimpleShapeEditor.tmpVec3);
			var addx=SimpleShapeEditor.tmpVec3.elements[0];
			var addy=SimpleShapeEditor.tmpVec3.elements[2];
			var nx=dt[stid%dt.length].x;
			var ny=dt[stid%dt.length].y;
			dt.splice(stid,0,new HandlePoint(addx,addy,(addx+nx)/2,(addy+ny)/2));
			this.target._simpleShapeMesh.onDataChanged();
			this.updateData();
			this.undo_op_end();
			}else if (this.pickEdgeResult.ObjID==1){
			this.undo_startProfileData();
			this.undo_drage_changeData();
			dt=this.target._simpleShapeMesh.profileLineData;
			stid=this.pickEdgeResult.PtIdx+1;
			this.scrToLocalPlane(this.pickEdgeResult.projX,this.pickEdgeResult.projY,SimpleShapeEditor.LOCAL_XY,SimpleShapeEditor.tmpVec3);
			addx=SimpleShapeEditor.tmpVec3.elements[0];
			addy=SimpleShapeEditor.tmpVec3.elements[1];
			nx=dt[stid].x;
			ny=dt[stid].y;
			dt.splice(stid,0,new HandlePoint(addx,addy,(addx+nx)/2,(addy+ny)/2));
			this.target._simpleShapeMesh.onDataChanged();
			this.updateData();
			this.undo_op_end();
		}
	}

	/**
	*编辑器一个完整的op结束了
	*/
	__proto.onEditorOpEnd=function(){}
	//添加到redo中
	__proto.onMouseDown=function(e){
		this.pick(e.stageX,e.stageY);
	}

	__proto.onMouseUp=function(e){
		this.pickResult.miniObjID=-1;
		this.pickResult.miniPointID=-1;
		this.undo_op_end();
	}

	/**
	*屏幕坐标转换到对象本地空间的坐标系平面。
	*@param x
	*@param y
	*@param planeid 只能是 LOCAL_XY， LOCAL_XZ， LOCAL_YZ 之一
	*@param out
	*/
	__proto.scrToLocalPlane=function(x,y,planeid,out){
		if (planeid !=SimpleShapeEditor.LOCAL_XY && planeid !=SimpleShapeEditor.LOCAL_XZ && planeid !=SimpleShapeEditor.LOCAL_YZ){
			console.error('planeid 不是指定值');
			return;
		};
		var planePos=Vec3Pool.getVec3();
		var planeNor=Vec3Pool.getVec3();
		var worldPos=Vec3Pool.getVec3();
		planePos.elements[0]=this.mat_World.elements[12];
		planePos.elements[1]=this.mat_World.elements[13];
		planePos.elements[2]=this.mat_World.elements[14];
		planeNor.elements[0]=this.mat_World.elements[planeid];planeNor.elements[1]=this.mat_World.elements[planeid+1];planeNor.elements[2]=this.mat_World.elements[planeid+2];
		this.scrToPlane(x,y,planePos,planeNor,worldPos);
		this.worldToLocal(worldPos,out);
		Vec3Pool.discardVec3(planeNor);
		Vec3Pool.discardVec3(planePos);
		Vec3Pool.discardVec3(worldPos);
	}

	__proto.onMouseMov=function(e){
		var dt;
		var lastx=0;
		var lasty=0;
		var mesh=this.target._simpleShapeMesh;
		if (this.pickResult.miniObjID >=0 && this.pickResult.miniPointID >=0){
			var mx=e.stageX+this.pickResult.offX;
			var my=e.stageY+this.pickResult.offY;
			var pointid=this.pickResult.miniPointID;
			switch (this.pickResult.miniObjID){
				case 0:{
						this.scrToLocalPlane(mx,my,SimpleShapeEditor.LOCAL_XZ,SimpleShapeEditor.tmpVec3);
						dt=mesh.crossSectionData;
						lastx=dt[pointid].x;
						lasty=dt[pointid].y;
						dt[pointid].x=SimpleShapeEditor.tmpVec3.x;
						dt[pointid].y=SimpleShapeEditor.tmpVec3.z;
						dt[pointid].ctrlx+=(SimpleShapeEditor.tmpVec3.x-lastx);
						dt[pointid].ctrly+=(SimpleShapeEditor.tmpVec3.z-lasty);
						mesh.onDataChanged();
					}
					break ;
				case 1:{
						this.scrToLocalPlane(mx,my,SimpleShapeEditor.LOCAL_XY,SimpleShapeEditor.tmpVec3);
						dt=mesh.profileLineData;
						lastx=dt[pointid].x;
						lasty=dt[pointid].y;
						dt[pointid].x=SimpleShapeEditor.tmpVec3.x;
						dt[pointid].y=SimpleShapeEditor.tmpVec3.y;
						dt[pointid].ctrlx+=(SimpleShapeEditor.tmpVec3.x-lastx);
						dt[pointid].ctrly+=(SimpleShapeEditor.tmpVec3.y-lasty);
						mesh.onDataChanged();
					}
					break ;
				case 2:{
						this.scrToLocalPlane(mx,my,SimpleShapeEditor.LOCAL_XZ,SimpleShapeEditor.tmpVec3);
						dt=mesh.crossSectionData;
						dt[pointid].ctrlx=SimpleShapeEditor.tmpVec3.x;
						dt[pointid].ctrly=SimpleShapeEditor.tmpVec3.z;
						mesh.onDataChanged();
					}
					break ;
				case 3:{
						this.scrToLocalPlane(mx,my,SimpleShapeEditor.LOCAL_XY,SimpleShapeEditor.tmpVec3);
						dt=mesh.profileLineData;
						dt[pointid].ctrlx=SimpleShapeEditor.tmpVec3.x;
						dt[pointid].ctrly=SimpleShapeEditor.tmpVec3.y;
						mesh.onDataChanged();
					}
					break ;
				default :
				}
			this.undo_drage_changeData();
		}
	}

	__proto.onKeyDown=function(e){
		var interpBase=3;
		switch(e.keyCode){
			case 27:
				break ;
			case 9:
				this.editMode=!this.editMode;
				break ;
			case 48:
			case 49:
			case 50:
			case 51:
			case 52:
			case 53:
			case 54:
			case 55:
			case 56:
			case 57:
				if (this.ctrl){
					e.stopPropagation();
					this.interpNum=interpBase *(e.keyCode-48);
					this.undo_op_changeInterp(this.target._simpleShapeMesh.profileLineInterpNum,this.interpNum);
					this.target._simpleShapeMesh.profileLineInterpNum=this.target._simpleShapeMesh.crossSectionInterpNum=this.interpNum;
				}
				break ;
			case 17:
				this.ctrl=true;
				break ;
			case 90:
				this.ctrl && this.undo();
				break ;
			case 89:
				this.ctrl && this.redo();
				break ;
			case 83:{
					var curstyle=this.target._simpleShapeMesh.polygonStyle;
					e.stopPropagation();
					this.target._simpleShapeMesh.polygonStyle=!curstyle;
					this.undo_op_changeStyle(curstyle ,!curstyle);
				}
				break ;
			}
	}

	__proto.onKeyUp=function(e){
		switch(e.keyCode){
			case 17:
				this.ctrl=false;
				break ;
			}
	}

	__proto.onDbClick=function(e){
		this.pick(e.stageX,e.stageY,20);
		if (this.pickResult.miniObjID >=0 && this.pickResult.miniPointID >=0){
			this.deletePoint(this.pickResult.miniObjID,this.pickResult.miniPointID);
			}else {
			this.addPoint(e.stageX,e.stageY);
		}
	}

	/**
	*需要提供的数据：
	*。可控点 （垂直于镜头的黑色小方块）
	*。连边（放在这里是否合适）（黑色。选中状态是土黄色渐变）
	*。移动限制。（亮黄色）
	*。如果是线限制的话，可以提供当前值（长度）
	*。
	*/
	__proto.renderVisualData=function(g){
		if (!this.editMode)
			return;
		var mat_World=this.target.transform.worldMatrix;
		g.alpha(0.5);
		var pos=new Vector3$1(mat_World.elements[12],mat_World.elements[13],mat_World.elements[14]);
		var scrPos=new Vector3$1();
		this.localToScreen(pos,scrPos);
		var orix=scrPos.x;
		var oriy=scrPos.y;
		var oriz=scrPos.z;
		if (scrPos.z >0){
			pos.x+=1;
			this.localToScreen(pos,scrPos);
			if (scrPos.z > 0){}
				pos.x-=1;pos.y+=1;
			this.localToScreen(pos,scrPos);
			if (scrPos.z > 0){}
				pos.y-=1;pos.z+=1;
			this.localToScreen(pos,scrPos);
			if (scrPos.z > 0){}
				}
		pos.x=0;pos.y=this.target._simpleShapeMesh.profileLineMiniY;pos.z=0;
		this.localToScreen(pos,scrPos);
		var osx=scrPos.x;
		var osy=scrPos.y;
		var osz=scrPos.z;
		pos.y=this.target._simpleShapeMesh.profileLineMaxY;
		this.localToScreen(pos,scrPos);
		if (osz > 0 && scrPos.z > 0){
			g.drawLine(osx,osy,scrPos.x,scrPos.y,'#007700');
		};
		var interp=this.target._simpleShapeMesh.crossSectionInterpNum;
		var cx=NaN;
		var cy=NaN;
		var hdatanum=this.crossDataOnScr.length / 2;
		for (var hi=0;hi < hdatanum;hi++){
			var nex=(hi+1)% hdatanum;
			var curz=this.crossDataOnScrZ[hi];
			var nextz=this.crossDataOnScrZ[nex];
			cx=this.crossDataOnScr[hi *2];
			cy=this.crossDataOnScr[hi *2+1];
			var nexx=this.crossDataOnScr[nex *2];
			var nexy=this.crossDataOnScr[nex *2+1];
			if (curz > 0){
				g.drawRect(cx-4,cy-4,8,8,'#ffff44');
				if (nextz > 0){
					g.drawLine(cx,cy,nexx,nexy,'#999900');
					if (interp > 0){
						if (this.crossCtrlOnScrZ[hi] > 0){
							var ctrlx=this.crossCtrlOnScr[hi *2];
							var ctrly=this.crossCtrlOnScr[hi *2+1];
							g.drawRect(ctrlx-4,ctrly-4,8,8,'#ff0000');
							g.drawLine(cx,cy,ctrlx,ctrly,'#880000');
						}
					}
				}else {}
				}else {
				if (nextz > 0){
					}else {
					continue ;
				}
			}
		};
		var cdtNum=this.profileLineDataOnScr.length / 2;
		for (var ci=0;ci < cdtNum;ci++){
			var cz=this.profileLineDataOnScrZ[ci];
			cx=this.profileLineDataOnScr[ci *2];
			cy=this.profileLineDataOnScr[ci *2+1];
			if(cz>0){
				g.drawRect(cx-4,cy-4,8,8,'#44ffff');
			}
			if (ci < cdtNum-1){
				var nz=this.profileLineDataOnScrZ[ci+1];
				if (cz > 0 && nz > 0){
					g.drawLine(cx,cy,this.profileLineDataOnScr[ci *2+2],this.profileLineDataOnScr[ci *2+3],'#009999');
					if (interp > 0){
						if (this.profileCtrlOnScrZ[ci] > 0){
							ctrlx=this.profileCtrlOnScr[ci *2];
							ctrly=this.profileCtrlOnScr[ci *2+1];
							g.drawRect(ctrlx-4,ctrly-4,8,8,'#ff0000');
							g.drawLine(cx,cy,ctrlx,ctrly,'#880000');
						}
					}
				}
			}
			if (interp > 0){}
				}
	}

	SimpleShapeEditor.canEditObject=function(){
		return "SimpleShapeSprite3D";
	}

	SimpleShapeEditor.LOCAL_YZ=0;
	SimpleShapeEditor.LOCAL_XZ=4;
	SimpleShapeEditor.LOCAL_XY=8;
	SimpleShapeEditor.UndoStackLen=100;
	__static(SimpleShapeEditor,
	['tmpMat',function(){return this.tmpMat=new Matrix4x4$1();},'tmpVec3',function(){return this.tmpVec3=new Vector3$1();},'tmpVec31',function(){return this.tmpVec31=new Vector3$1();}
	]);
	return SimpleShapeEditor;
})()


//class laya.d3Extend.worldMaker.UndoOperation
var UndoOperation=(function(){
	function UndoOperation(){
		this.opName='NO';
		this.desc="";
	}

	__class(UndoOperation,'laya.d3Extend.worldMaker.UndoOperation');
	return UndoOperation;
})()


//class laya.d3Extend.worldMaker.Vec3Pool
var Vec3Pool=(function(){
	function Vec3Pool(){}
	__class(Vec3Pool,'laya.d3Extend.worldMaker.Vec3Pool');
	Vec3Pool.getVec3=function(){
		var ret;
		if (Vec3Pool.vecstack.length){
			ret=Vec3Pool.vecstack.pop();
			}else {
			ret=new Vector3$1();
		}
		return ret;
	}

	Vec3Pool.discardVec3=function(v){
		v.elements[0]=v.elements[1]=v.elements[2]=0;
		Vec3Pool.vecstack.push(v);
	}

	Vec3Pool.vecstack=[];
	return Vec3Pool;
})()


/**
*/
//class laya.d3Extend.worldMaker.SimpleShapeFilter extends laya.d3.core.GeometryElement
var SimpleShapeFilter=(function(_super){
	function SimpleShapeFilter(bEditMode){
		this.indexNum=0;
		this.vertexNum=0;
		//public var crossSectionSplineCtrl:Array=[];// 二次贝塞尔曲线的控制点。有几个点就有几个控制点，不管是否是封闭的
		this._crossSecInterpNum=0;
		//public var profileLineDataSplineCtrl:Array=[];
		this._profilelineInterfNum=0;
		//侧面的插值次数
		this._color=0xffffff;
		//bgr
		this._polygonStyle=true;
		this.needReExport=true;
		this._bEditMode=false;
		//编辑器模式下，会有一个缺省外观，并且修改参数会立即导出
		this._bbx=[0,0,0,0,0,0];
		this.exported=false;
		this.profileLineMiniY=0;
		this.profileLineMaxY=0;
		this._splineType='bezier2interp';
		SimpleShapeFilter.__super.call(this);
		this.boundSphere=new BoundSphere(new Vector3$1(6,6,6),10.392);
		this.crossSectionData=[];
		this.profileLineData=[];
		this.leMesh=new LE_Mesh();
		(bEditMode===void 0)&& (bEditMode=false);
		this._bEditMode=bEditMode;
		this.setCrossSection([-0.309,0.951,0.154,0.4755,0.809,0.587,0.5,0,0.809,-0.587,0.154,-0.475,-0.309,-0.951,-0.404,-0.293,-1,0,-0.404,0.293]);
		this.setProfileLine([0.01,0.1,1,0 ,0.01,0.3]);
		if(bEditMode){
			this.rebuildMesh();
			this.reExportMeshData();
		}
	}

	__class(SimpleShapeFilter,'laya.d3Extend.worldMaker.SimpleShapeFilter',_super);
	var __proto=SimpleShapeFilter.prototype;
	/**
	*二次贝塞尔曲线
	*@param sx 起点
	*@param sy
	*@param ex 终点
	*@param ey
	*@param cx 控制点
	*@param cy
	*@param interpNum 插值次数
	*@return 返回插值后的数组
	*/
	__proto.bezier2=function(sx,sy,ex,ey,cx,cy,interpNum){
		var ret=new Array(interpNum*2);
		var changeX1=(cx-sx)/ interpNum;
		var changeY1=(cy-sy)/ interpNum;
		var changeX2=(ex-cx)/ interpNum;
		var changeY2=(ey-cy)/ interpNum;
		for(var i=0;i < interpNum;i++){
			var qx1=sx+changeX1 *i;
			var qy1=sy+changeY1 *i;
			var qx2=cx+changeX2 *i;
			var qy2=cy+changeY2 *i;
			var bx=qx1+(qx2-qx1)*i / interpNum;
			var by=qy1+(qy2-qy1)*i / interpNum;
			ret[i *2]=bx;
			ret[i *2+1]=by;
		}
		return ret;
	}

	/**
	*三次贝塞尔曲线
	*/
	__proto.PointOnCubicBezier=function(){}
	/**
	*把一个折线用贝塞尔插值。
	*@param data
	*@param interpNum 每一段插成多少段
	*@param close 是否是闭合
	*@return
	*/
	__proto.bezier2interp=function(data,interpNum,close){
		if (data.length < 2)
			return [];
		var i=0;
		var ret=[];
		var ptnum=data.length;
		if (interpNum==0){
			for (i=0;i < ptnum;i++){
				ret.push(data[i].x,data[i].y);
			}
			return ret;
		};
		var ci=0;
		for (i=0;i < ptnum-1;i++){
			ret=ret.concat(this.bezier2(data[i].x,data[i].y,data[i+1].x,data[i+1].y,data[i].ctrlx,data[i].ctrly,interpNum));
		}
		if (close){
			var last=data[data.length-1];
			ret=ret.concat(this.bezier2(last.x,last.y,data[0].x,data[0].y,last.ctrlx,last.ctrly,interpNum));
		}
		return ret;
	}

	/**
	*根据数据重新生成渲染模型
	*/
	__proto.rebuildMesh=function(){
		var interpFun=this[this._splineType];
		this.leMesh.createFromCrossSection_taperPath(
		interpFun.call(this,this.crossSectionData,this._crossSecInterpNum,true),
		true,
		interpFun.call(this,this.profileLineData,this._profilelineInterfNum,false),
		null);
	}

	/**
	*@private
	*@return 是否需要渲染。
	*/
	__proto._prepareRender=function(state){
		if (!this.exported){
			this.rebuildMesh();
			this.reExportMeshData();
		}
		return true;
	}

	__proto.updateBBX=function(x,y,z){
		if (this._bbx[0] > x)this._bbx[0]=x;
		if (this._bbx[1] > y)this._bbx[1]=y;
		if (this._bbx[2] > z)this._bbx[2]=z;
		if (this._bbx[3] < x)this._bbx[3]=x;
		if (this._bbx[4] < y)this._bbx[4]=y;
		if (this._bbx[5] < z)this._bbx[5]=z;
	}

	__proto.getBBXCenter=function(vout){
		vout.x=(this._bbx[0]+this._bbx[3])/ 2;
		vout.y=(this._bbx[1]+this._bbx[4])/ 2;
		vout.z=(this._bbx[2]+this._bbx[5])/ 2;
	}

	//包围盒的对角线
	__proto.getBBXSize=function(){
		var dx=this._bbx[3]-this._bbx[0];
		var dy=this._bbx[4]-this._bbx[1];
		var dz=this._bbx[5]-this._bbx[2];
		return Math.sqrt(dx *dx+dy *dy+dz *dz);
	}

	/**
	*重新导出模型
	*/
	__proto.reExportMeshData=function(){
		var expmesh=this.leMesh.fastExportRenderableMesh(this.polygonStyle?1:0);
		var vertnum=this.vertexNum=expmesh.pos.length / 3;
		var vd=VertexPositionNormalColor.vertexDeclaration;
		var Buffers=__newvec(1,null);
		var vb=new VertexBuffer3D(vd.vertexStride *vertnum*4,0x88E8,true);
		var vbbuf=new Float32Array(vd.vertexStride *vertnum);
		var vi=0;
		var pi=0;
		var ni=0;
		var ci=0;
		var cr=(this._color&0xff)/255.0;
		var cg=((this._color>>>8)&0xff)/255.0;
		var cb=((this._color>>>16)&0xff)/255.0;
		var ca=1.0;
		var cx=0;
		var cy=0;
		var cz=0;
		for (var i=0;i < vertnum;i++){
			cx=expmesh.pos[pi++];
			cy=expmesh.pos[pi++];
			cz=expmesh.pos[pi++];
			vbbuf[vi++]=cx;vbbuf[vi++]=cy;vbbuf[vi++]=cz;
			this.updateBBX(cx,cy,cz);
			vbbuf[vi++]=expmesh.normal[ni++];vbbuf[vi++]=expmesh.normal[ni++];vbbuf[vi++]=expmesh.normal[ni++];
			vbbuf[vi++]=cr;vbbuf[vi++]=cg;vbbuf[vi++]=cb;vbbuf[vi++]=ca;
		}
		vb.setData(vbbuf);
		vb.vertexDeclaration=vd;
		Buffers[0]=vb;
		this.getBBXCenter(this.boundSphere.center);
		this.boundSphere.radius=this.getBBXSize()/2;
		this.indexNum=expmesh.index.length;
		var ib=new IndexBuffer3D("ushort",expmesh.index.length,0x88E8);
		ib.setData(expmesh.index);
		var bufferState=new BufferState();
		bufferState.bind();
		bufferState.applyVertexBuffers(Buffers);
		bufferState.applyIndexBuffer(ib);
		bufferState.unBind();
		this._applyBufferState(bufferState);
		this.exported=true;
	}

	/**
	*设置模型的横截面
	*@param data
	*/
	__proto.setCrossSection=function(data){
		if (!data || data.length<=0)return;
		if (typeof(data[0])=='number'){
			var i=0;
			var cx=0,cy=0,nx=0,ny=0;
			var ptnum=data.length / 2;
			this.crossSectionData.length=ptnum;
			for (i=0;i < ptnum;i++){
				cx=data[i *2];
				cy=data[i *2+1];
				nx=data[(i *2+2)% data.length];
				ny=data[(i *2+3)% data.length];
				this.crossSectionData[i]=new HandlePoint(cx,cy,(cx+nx)/ 2,(cy+ny)/ 2);
			}
			}else {
			this.crossSectionData=data;
		}
		this.onDataChanged();
	}

	__proto.onDataChanged=function(){
		if (this._bEditMode){
			this.rebuildMesh();
			this.reExportMeshData();
			}else {
			this.exported=false;
		}
		if(this.profileLineData && this.profileLineData.length){
			this.profileLineMiniY=this.profileLineData[0].y;
			this.profileLineMaxY=this.profileLineMiniY+1;
			for (var i=1;i < this.profileLineData.length;i++){
				var cy=this.profileLineData[i].y;
				if (cy < this.profileLineMiniY)this.profileLineMiniY=cy;
				if (cy > this.profileLineMaxY)this.profileLineMaxY=cy;
			}
		}
	}

	/**
	*设置侧面线，
	*@param data 是一个数组，x表示缩放，y表示高度
	*/
	__proto.setProfileLine=function(data){
		if (!data || data.length<=0)return;
		if (typeof(data[0])=='number'){
			var i=0;
			var cx=0,cy=0,nx=0,ny=0;
			var ptnum=data.length / 2;
			this.profileLineData.length=ptnum;
			for (i=0;i < ptnum;i++){
				cx=data[i *2];
				cy=data[i *2+1];
				nx=data[(i *2+2)% data.length];
				ny=data[(i *2+3)% data.length];
				this.profileLineData[i]=new HandlePoint(cx,cy,(cx+nx)/ 2,(cy+ny)/ 2);
			}
			}else {
			this.profileLineData=data;
		}
		if(this._bEditMode){
			this.rebuildMesh();
			this.reExportMeshData();
			}else {
			this.exported=false;
		}
	}

	//
	__proto._render=function(state){
		var gl=LayaGL.instance;
		gl.drawElements(0x0004,this.indexNum,0x1403,0);
		Stat.drawCall+=1;
		Stat.trianglesFaces+=this.indexNum/3;
	}

	__proto._destroy=function(){}
	__getset(0,__proto,'crossSectionInterpNum',function(){
		return this._crossSecInterpNum;
		},function(i){
		if(this._crossSecInterpNum!=i){
			this._crossSecInterpNum=i;
			if(this._bEditMode){
				this.rebuildMesh();
				this.reExportMeshData();
				}else {
				this.exported=false;
			}
		}
	});

	/**
	*仅供读写文件用
	*/
	__getset(0,__proto,'splineType',function(){
		return this._splineType;
		},function(type){
		this._splineType=type;
	});

	/**
	*是否为多边形风格
	*@param b
	*/
	__getset(0,__proto,'polygonStyle',function(){
		return this._polygonStyle;
		},function(b){
		if(b!=this._polygonStyle){
			this._polygonStyle=b;
			if(this._bEditMode){
				this.reExportMeshData();
				}else {
				this.exported=false;
			}
		}
	});

	__getset(0,__proto,'profileLineInterpNum',function(){
		return this._profilelineInterfNum;
		},function(i){
		if (this._profilelineInterfNum !=i){
			this._profilelineInterfNum=i;
			if(this._bEditMode){
				this.rebuildMesh();
				this.reExportMeshData();
				}else {
				this.exported=false;
			}
		}
	});

	/**
	*color 格式是 0xbbggrr
	*/
	__getset(0,__proto,'color',function(){
		return this._color;
		},function(color){
		if (this._color !=color){
			this._color=color;
			if (this._bEditMode){
				this.reExportMeshData();
				}else {
				this.exported=false;
			}
		}
	});

	__getset(0,__proto,'roughness',function(){
		return 1;
		},function(r){
	});

	return SimpleShapeFilter;
})(GeometryElement)


/**
*...
*Miner ...
*/
//class laya.d3Extend.VertexColor extends laya.d3.graphics.Vertex.VertexMesh
var VertexColor=(function(_super){
	function VertexColor(color){
		this._color=null;
		VertexColor.__super.call(this);
		this._color=color;
	}

	__class(VertexColor,'laya.d3Extend.VertexColor',_super);
	var __proto=VertexColor.prototype;
	__getset(0,__proto,'Color',function(){
		return this._color;
	});

	__getset(0,__proto,'vertexDeclaration',function(){
		return VertexColor._vertexDeclaration;
	});

	/*INTERFACE laya.d3.graphics.IVertex */
	__getset(1,VertexColor,'vertexDeclaration',function(){
		return VertexColor._vertexDeclaration;
	},laya.d3.graphics.Vertex.VertexMesh._$SET_vertexDeclaration);

	__static(VertexColor,
	['_vertexDeclaration',function(){return this._vertexDeclaration=new VertexDeclaration(16,[
		new VertexElement(0,"vector4",1)]);}
	]);
	return VertexColor;
})(VertexMesh)


//class laya.d3Extend.worldMaker.SimpleShapeRenderer extends laya.d3.core.render.BaseRender
var SimpleShapeRenderer=(function(_super){
	function SimpleShapeRenderer(owner){
		this._projectionViewWorldMatrix=null;
		this.boundsph=new BoundSphere(new Vector3$1(),1.0);
		SimpleShapeRenderer.__super.call(this,owner,4);
		this._projectionViewWorldMatrix=new Matrix4x4$1();
	}

	__class(SimpleShapeRenderer,'laya.d3Extend.worldMaker.SimpleShapeRenderer',_super);
	var __proto=SimpleShapeRenderer.prototype;
	__proto._onMeshChanged=function(meshFilter,oldMesh,mesh){
		this._onMeshLoaed();
	}

	__proto._onMeshLoaed=function(){
		this._boundingSphereNeedChange=true;
		this._boundingBoxNeedChange=true;
		this._boundingBoxCenterNeedChange=true;
		this._octreeNodeNeedChange=true;
	}

	//计算包围盒根据原始包围盒
	__proto._calculateBoundBoxByInitCorners=function(corners){
		var worldMat=(this._owner).transform.worldMatrix;
		for (var i=0;i < 8;i++)
		BoundBox.createfromPoints(BaseRender._tempBoundBoxCorners,this._boundingBox);
		Vector3$1.transformCoordinate(corners[i],worldMat,BaseRender._tempBoundBoxCorners[i]);
	}

	//计算球包围盒
	__proto._calculateBoundingSphere=function(){
		var boundSphere=(this._owner)._simpleShapeMesh.boundSphere;
		var maxScale=NaN;
		var transform=this._owner.transform;
		var scaleE=transform.scale.elements;
		var scaleX=scaleE[0];
		scaleX || (scaleX=-scaleX);
		var scaleY=scaleE[1];
		scaleY || (scaleY=-scaleY);
		var scaleZ=scaleE[2];
		scaleZ || (scaleZ=-scaleZ);
		if (scaleX >=scaleY && scaleX >=scaleZ)
			maxScale=scaleX;
		else
		maxScale=scaleY >=scaleZ ? scaleY :scaleZ;
		Vector3$1.transformCoordinate(boundSphere.center,transform.worldMatrix,this._boundingSphere.center);
		this._boundingSphere.radius=boundSphere.radius *maxScale;
	}

	//计算Box包围盒
	__proto._calculateBoundingBox=function(){
		var sharedMesh=(this._owner).meshFilter.sharedMesh;
		if (sharedMesh==null || sharedMesh.boundingBox==null)
			this._boundingBox.toDefault();
		else
		this._calculateBoundBoxByInitCorners(sharedMesh.boundingBoxCorners);
	}

	//判断是否需要渲染
	__proto._needRender=function(boundFrustum){
		return true;
	}

	//更新模型位置
	__proto._renderUpdate=function(context,transform){
		if (transform)
			this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX,transform.worldMatrix);
		else
		this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX,Matrix4x4$1.DEFAULT);
	}

	//更新模型照相机位置
	__proto._renderUpdateWithCamera=function(context,transform){
		var projectionView=context.projectionViewMatrix;
		if (transform){
			Matrix4x4$1.multiply(projectionView,transform.worldMatrix,this._projectionViewWorldMatrix);
			this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX,this._projectionViewWorldMatrix);
			}else {
			this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX,projectionView);
		}
		if (Laya3D.debugMode)
			this._renderRenderableBoundBox();
	}

	//删除
	__proto._destroy=function(){}
	return SimpleShapeRenderer;
})(BaseRender)


/**
*...
*@author ...
*/
//class laya.d3Extend.worldMaker.SimpleShapeSprite3D extends laya.d3.core.RenderableSprite3D
var SimpleShapeSprite3D=(function(_super){
	function SimpleShapeSprite3D(props){
		this._simpleShapeMesh=null;
		this._editor=null;
		SimpleShapeSprite3D.__super.call(this,null);
		this._render=new SimpleShapeRenderer(this);
		this._simpleShapeMesh=new SimpleShapeFilter(props && props.isEditor);
		var renderElement=new RenderElement();
		this._render._renderElements.push(renderElement);
		this._render._defineDatas.add(MeshSprite3D.SHADERDEFINE_COLOR);
		renderElement.setTransform(this._transform);
		renderElement.render=this._render;
		var mat=this._render.sharedMaterial;
		mat || (mat=new BlinnPhongMaterial());
		mat.albedoColor=new Vector4$1(1.0,0.0,0.0,1.0);
		renderElement.material=mat;
		renderElement.setGeometry(this._simpleShapeMesh);
		for (var k in props){
			this[k]=props[k];
		}
	}

	__class(SimpleShapeSprite3D,'laya.d3Extend.worldMaker.SimpleShapeSprite3D',_super);
	var __proto=SimpleShapeSprite3D.prototype;
	/**
	*@inheritDoc
	*/
	__proto._parse=function(data){}
	__proto.onSelect=function(){
		this._editor.onSelect();
	}

	__proto.onUnselect=function(){
		this._editor.onUnselect();
		this._editor=null;
	}

	__proto.getEditor=function(cam){
		if(!this._editor){
			this._editor=new SimpleShapeEditor(this,cam);
		}
		return this._editor;
	}

	return SimpleShapeSprite3D;
})(RenderableSprite3D)


	Laya.__init([LE_Mesh]);
})(window,document,Laya);

if (typeof define === 'function' && define.amd){
	define('laya.core', ['require', "exports"], function(require, exports) {
        'use strict';
        Object.defineProperty(exports, '__esModule', { value: true });
        for (var i in Laya) {
			var o = Laya[i];
            o && o.__isclass && (exports[i] = o);
        }
    });
}